package drds.plus.executor.command_handler.put;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.ExecutorException;
import drds.plus.executor.command_handler.CommonCommandHandler;
import drds.plus.executor.command_handler.TableWithIndexMetaData;
import drds.plus.executor.cursor.cursor.IAffectRowCursor;
import drds.plus.executor.cursor.cursor.ISortingCursor;
import drds.plus.executor.table.ITable;
import drds.plus.executor.transaction.Transaction;
import drds.plus.sql_process.abstract_syntax_tree.configuration.IndexMapping;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlan;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.dml.IPut;

/**
 * CUD操作基类
 */
public abstract class PutHandler extends CommonCommandHandler {

    public PutHandler() {
        super();
    }

    public ISortingCursor handle(ExecuteContext executeContext, ExecutePlan executePlan) throws RuntimeException {

        if (executeContext.getParameters() != null && executeContext.getParameters().isBatch()) {
            throw new ExecutorException("batch is not supported for :" + executeContext.getRepository().getClass());
        }
        IPut put = (IPut) executePlan;
        TableWithIndexMetaData tableWithIndexMetaData = new TableWithIndexMetaData();
        prepareTableAndIndexMetaDataForPut(executeContext, put, tableWithIndexMetaData);

        int affectRows = 0;
        Transaction transaction = executeContext.getTransaction();
        ITable table = tableWithIndexMetaData.table;
        IndexMapping indexMapping = tableWithIndexMetaData.indexMapping;
        try {
            if (transaction == null) {// 客户端没有用事务，这里手动加上。
                throw new IllegalAccessError("txn is null");
            }
            affectRows = executePut(executeContext, put, table, indexMapping);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 这里返回key->value的方式的东西，类似Key=affectRow val=1 这样的软编码
        IAffectRowCursor affectRowCursor = executeContext.getRepository().getCursorFactory().affectRowCursor(executeContext, affectRows);
        return affectRowCursor;

    }

    protected abstract int executePut(ExecuteContext executeContext, IPut put, ITable table, IndexMapping meta) throws Exception;


}
